package com.pangu.web.view;

import java.util.Enumeration;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public abstract class AbstractTemplateView extends AbstractView {

	private boolean exposeRequestAttributes = false;

	private boolean allowRequestOverride = false;

	private boolean exposeSessionAttributes = false;

	private boolean allowSessionOverride = false;

	public void setExposeRequestAttributes(boolean exposeRequestAttributes) {
		this.exposeRequestAttributes = exposeRequestAttributes;
	}

	public void setExposeSessionAttributes(boolean exposeSessionAttributes) {
		this.exposeSessionAttributes = exposeSessionAttributes;
	}

	public void setAllowRequestOverride(boolean allowRequestOverride) {
		this.allowRequestOverride = allowRequestOverride;
	}

	public void setAllowSessionOverride(boolean allowSessionOverride) {
		this.allowSessionOverride = allowSessionOverride;
	}

	@Override
	protected void renderMergedOutputModel(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) throws Throwable {

		if (this.exposeRequestAttributes) {
			for (@SuppressWarnings("rawtypes")
			Enumeration en = request.getAttributeNames(); en.hasMoreElements();) {
				String attribute = (String) en.nextElement();
				if (model.containsKey(attribute) && !this.allowRequestOverride)
					log.warn("Cannot expose request attribute '"
							+ attribute + "' because of an existing model object of the same name");
				else {
					Object attributeValue = request.getAttribute(attribute);
					if (log.isDebugEnabled()) {
						log.debug("Exposing request attribute '" + attribute
								+ "' with value [" + attributeValue + "] to model");
					}
					model.put(attribute, attributeValue);
				}
			}
		}
		
		if (this.exposeSessionAttributes) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				for (@SuppressWarnings("rawtypes")
				Enumeration en = session.getAttributeNames(); en.hasMoreElements();) {
					String attribute = (String) en.nextElement();
					if (model.containsKey(attribute) && !this.allowSessionOverride)
						log.warn("Cannot expose session attribute '" + attribute 
								+ "' because of an existing model object of the same name");
					else {
						Object attributeValue = session.getAttribute(attribute);
						if (log.isDebugEnabled()) {
							log.debug("Exposing session attribute '" + attribute +
									"' with value [" + attributeValue + "] to model");
						}
						model.put(attribute, attributeValue);
					}
				}
			}
		}

		renderMergedTemplateModel(model, request, response);
	}
	
	protected abstract void renderMergedTemplateModel(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response) throws Throwable;
}
